package com.xmtlxx.web.controller.oms.controller;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.bean.BeanUtil;
import com.xmtlxx.common.annotation.Log;
import com.xmtlxx.common.annotation.RepeatSubmit;
import com.xmtlxx.common.core.controller.BaseController;
import com.xmtlxx.common.core.domain.PageQuery;
import com.xmtlxx.common.core.domain.R;
import com.xmtlxx.common.core.page.TableDataInfo;
import com.xmtlxx.common.core.validate.AddGroup;
import com.xmtlxx.common.core.validate.EditGroup;
import com.xmtlxx.common.core.validate.QueryGroup;
import com.xmtlxx.common.enums.BusinessType;
import com.xmtlxx.common.exception.ServiceException;
import com.xmtlxx.common.utils.poi.ExcelUtil;
import com.xmtlxx.oms.domain.Task;
import com.xmtlxx.oms.domain.bo.*;
import com.xmtlxx.oms.domain.vo.DisposalProVo;
import com.xmtlxx.oms.domain.vo.RegionOverviewVo;
import com.xmtlxx.oms.domain.vo.TaskDtlVo;
import com.xmtlxx.oms.domain.vo.TaskVo;
import com.xmtlxx.oms.service.ITaskDtlService;
import com.xmtlxx.web.controller.center.service.ICommonService;
import com.xmtlxx.web.controller.center.vo.SendTaskVo;
import com.xmtlxx.web.controller.oms.service.IDisposalTaskService;
import com.xmtlxx.web.controller.oms.service.ITaskService;
import com.xmtlxx.web.controller.wms.service.IExWarehouseService;
import com.xmtlxx.wms.domain.ExWarehouse;
import com.xmtlxx.wms.domain.bo.ExWarehouseBo;
import com.xmtlxx.wms.domain.bo.HandoverBo;
import com.xmtlxx.wms.domain.vo.ExWarehouseDtlVo;
import com.xmtlxx.wms.domain.vo.ExWarehouseVo;
import com.xmtlxx.wms.domain.vo.InventoryVo;
import com.xmtlxx.wms.service.IInventoryService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Validated
@Api(value = "处置订单控制器", tags = {"处置订单管理"})
@RequiredArgsConstructor
@RestController
@RequestMapping("/oms/task/disposal")
public class DisposalTaskController extends BaseController {

    private final IDisposalTaskService disposalTaskService;

    private final ITaskService iTaskService;

    private final ITaskDtlService iTaskDtlService;

    private final IExWarehouseService iExWarehouseService;

    private final IInventoryService iInventoryService;

    private final ICommonService commonService;

    /**
     * 返回一个初始化的对象到前端，方便进行动态渲染
     */
    @ApiOperation("用于返回一个初始化对象")
    @PostMapping("/initBean")
    public R<TaskVo> initBean(@Validated(AddGroup.class) @RequestBody TaskVo taskVo) {

        return R.ok(disposalTaskService.initBean(taskVo));
    }

    @ApiOperation("新增处置申请")
    @SaCheckPermission("oms:task:add")
    @Log(title = "处置申请", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping()
    @Transactional(rollbackFor = Exception.class)
    public R<Void> addDisposalApply(@Validated(AddGroup.class) @RequestBody TaskDisposalApplyBo bo) {

        disposalTaskService.disposalApply(bo);
        return R.ok();
    }

    @ApiOperation("修改处置")
    @SaCheckPermission("oms:task:add")
    @Log(title = "处置申请", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PutMapping()
    @Transactional(rollbackFor = Exception.class)
    public R<Void> disposalUpdate(@Validated(AddGroup.class) @RequestBody TaskDisposalApplyBo bo) {

        disposalTaskService.disposalUpdate(bo);
        return R.ok();
    }


    @ApiOperation("获取处置订单详细信息")
    @GetMapping("/{id}")
    public R<TaskVo> getInfo(@ApiParam("主键")
                             @NotNull(message = "主键不能为空")
                             @PathVariable("id") String id) {

        return R.ok(disposalTaskService.getTaskById(id));
    }

    @ApiOperation("查询处置未登记区域总览")
    @SaCheckPermission("oms:task:list")
    @GetMapping("/getNotRegisterOverview")
    public R<List<RegionOverviewVo>> getDisposalNotRegisterOverview() {

        return R.ok(disposalTaskService.getDisposalNotRegisterOverview());
    }

    @ApiOperation("查询处置未登记物品列表")
    @SaCheckPermission("oms:task:list")
    @GetMapping("/getNotRegisterList")
    public TableDataInfo<DisposalNotRegisterBo> getDisposalNotRegisterList(@Validated(QueryGroup.class) DisposalNotRegisterBo bo, PageQuery pageQuery) {

        return disposalTaskService.getDisposalNotRegisterPage(bo, pageQuery);
    }

    @ApiOperation("导出处置未登记物品列表")
    @SaCheckPermission("oms:task:export")
    @Log(title = "处置未登记订单", businessType = BusinessType.EXPORT)
    @PostMapping("/exportNotRegisterList")
    public void export(@Validated DisposalNotRegisterBo bo, HttpServletResponse response) {

        ExcelUtil.exportExcel(disposalTaskService.getDisposalNotRegisterList(bo), "处置未登记物品",
                DisposalNotRegisterBo.class, response);
    }

    @ApiOperation("查询处置物品信息")
    @GetMapping("/getDisposalProInfo/{pno}")
    public R<DisposalProVo> getDisposalProInfo(@PathVariable("pno") String pno) {

        return R.ok(disposalTaskService.getDisposalProInfo(pno));
    }

    //
//
//    @ApiOperation("新增出处置申请")
//    @SaCheckPermission("oms:task:add")
//    @Log(title = "处置申请", businessType = BusinessType.INSERT)
//    @RepeatSubmit()
//    @PostMapping()
//    public R<TaskVo> add(@Validated(AddGroup.class) @RequestBody TaskVo vo) {
//        TaskBo bo = new TaskBo();
//        BeanUtil.copyProperties(vo,bo);
//        TaskVo taskVo = disposalTaskService.insertByBo(bo);
//        //处置申请为自行配送时，自动下发
//        if(taskVo != null && taskVo.getDelivery().equals("1") && taskVo.getCheckStatus().equals("1")){
//            SendTaskVo sendTaskVo = new SendTaskVo();
//            sendTaskVo.setStoreId(taskVo.getStoreId());
//            sendTaskVo.setCarrierDeptId(0L);
//            String[] ids = new String[]{taskVo.getId()};
//            sendTaskVo.setIds(ids);
//            disposalTaskService.sendTask(sendTaskVo);
//        }
//        return R.ok(taskVo);
//    }
//
//
//    @ApiOperation("修改出处置申请")
//    @SaCheckPermission("oms:task:edit")
//    @Log(title = "处置申请", businessType = BusinessType.UPDATE)
//    @RepeatSubmit()
//    @PutMapping()
//    public R<TaskVo> edit(@Validated(EditGroup.class) @RequestBody TaskVo vo) {
//        TaskBo bo = new TaskBo();
//        BeanUtil.copyProperties(vo,bo);
//        return R.ok(disposalTaskService.updateByBo(bo));
//    }
//
//    /**
//     * 处置登记
//     */
//    @ApiOperation("处置登记")
//    @SaCheckPermission("oms:task:edit")
//    @Log(title = "处置登记", businessType = BusinessType.UPDATE)
//    @RepeatSubmit()
//    @PostMapping("/register")
//    public R<Void> register(@Validated(EditGroup.class) @RequestBody TaskVo vo) {
//        TaskBo bo = new TaskBo();
//        BeanUtil.copyProperties(vo,bo);
//        return toAjax(disposalTaskService.register(bo)?1:0);
//    }
//
    @ApiOperation("保存交接信息")
    @Log(title = "保存交接信息", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping("/handoverSave")
    @Transactional(rollbackFor = Exception.class)
    public R<Void> handoverSave(@Validated(EditGroup.class) @RequestBody HandoverBo bo) {

        return toAjax(disposalTaskService.handoverSave(bo));
    }

    @ApiOperation("处置申请下发")
    @SaCheckPermission("oms:task:edit")
    @Log(title = "处置申请下发", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PostMapping("/sendTask")
    @Transactional(rollbackFor = Exception.class)
    public R<Void> sendTask(@Validated(AddGroup.class) @RequestBody SendTaskVo vo) {

        disposalTaskService.sendTask(vo);
        return toAjax(1);
    }

    @ApiOperation("订单审核")
    @SaCheckPermission("oms:task:edit")
    @Log(title = "处置申请审核", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PostMapping("/check")
    @Transactional(rollbackFor = Exception.class)
    public R<Void> checkTask(@Validated(EditGroup.class) @RequestBody TaskVo taskVo) {

        if ("1".equals(taskVo.getCheckStatus())) {

            Task task = iTaskService.checkTask(taskVo);

            if (task != null) {
                TaskBo updatebo = new TaskBo();
                BeanUtil.copyProperties(task, updatebo);
                TaskDtlBo dtlBo = new TaskDtlBo();
                dtlBo.setTaskId(taskVo.getId());
                List<TaskDtlVo> dtls = iTaskDtlService.queryList(dtlBo);
                ExWarehouseBo exWarehouseBo = new ExWarehouseBo();
                exWarehouseBo.setTaskId(taskVo.getId());

                List<String> storeIds = dtls.stream().map(TaskDtlVo::getStoreId).distinct().collect(Collectors.toList());

                if (storeIds.size() == 1) {
                    exWarehouseBo.setStoreId(storeIds.get(0));
                } else if (storeIds.size() == 0) {
                    throw new ServiceException("物品不在仓库");
                } else if (storeIds.size() > 1) {
                    throw new ServiceException("物品在不同仓库");
                }
                String storeId = storeIds.get(0);

                List<ExWarehouseVo> exWarehouseVos = iExWarehouseService.queryList(exWarehouseBo);

                if (exWarehouseVos == null || exWarehouseVos.size() == 0) {
                    exWarehouseBo.setStoreId(storeId);
                    exWarehouseBo.setExno(taskVo.getTaskNo());
                    exWarehouseBo.setDeptId(taskVo.getDeptId());
                    exWarehouseBo.setType(taskVo.getType());
                    exWarehouseBo.setReason(taskVo.getRemark());
                    exWarehouseBo.setTargetId(taskVo.getDeptId());
                    exWarehouseBo.setContacts(taskVo.getName());
                    exWarehouseBo.setTel(taskVo.getTel());
                    exWarehouseBo.setAddress(taskVo.getAddress());
                    exWarehouseBo.setLng(taskVo.getLng());
                    exWarehouseBo.setLat(taskVo.getLat());
                    exWarehouseBo.setFlag(taskVo.getDelivery());
                    exWarehouseBo.setNums(taskVo.getNums());

                    List<ExWarehouseDtlVo> exDtls = new ArrayList<>();
                    if (dtls != null && dtls.size() > 0) {
                        for (TaskDtlVo dtl : dtls) {
                            ExWarehouseDtlVo exwdtl = new ExWarehouseDtlVo();
                            exwdtl.setPno(dtl.getPno());
                            exwdtl.setName(dtl.getName());
                            exwdtl.setDeptId(dtl.getDeptId());
                            exwdtl.setOrgId(dtl.getLocalId());
                            exwdtl.setNums(dtl.getNums());
                            exwdtl.setDelFlag("0");
                            exwdtl.setStatus("0");
                            exDtls.add(exwdtl);
                        }
                    } else {
                        throw new RuntimeException("无财物出库");
                    }
                    exWarehouseBo.setItems(exDtls);
                    ExWarehouse exWarehouse = iExWarehouseService.insertByBo(exWarehouseBo);
                }

                //更新下发状态
                updatebo.setStoreId(storeId);
                updatebo.setSendStatus("1");
                updatebo.setSendReStatus("1");
                iTaskService.updateTaskEnty(updatebo);
            }

        }
        return R.ok();
    }

    @ApiOperation("查询受托处置报表")
    @SaCheckPermission("oms:task:list")
    @GetMapping("/getAuthCenterDisposalList")
    public TableDataInfo<AuthCenterDisposalBo> getAuthCenterDisposalList() {

        return TableDataInfo.build(disposalTaskService.getAuthCenterDisposalList());
    }

    @ApiOperation("导出受托处置报表")
    @SaCheckPermission("oms:task:export")
    @Log(title = "受托处置报表", businessType = BusinessType.EXPORT)
    @PostMapping("/exportAuthCenterDisposalList")
    public void export(HttpServletResponse response) {

        ExcelUtil.exportExcel(disposalTaskService.getAuthCenterDisposalList(), "受托处置报表",
                AuthCenterDisposalBo.class, response);
    }


    @ApiOperation("处置结束")
    @Log(title = "处置结束", businessType = BusinessType.UPDATE)
    @SaCheckPermission("oms:task:list")
    @RepeatSubmit()
    @PostMapping("finish/{id}")
    @Transactional(rollbackFor = Exception.class)
    public R<Void> disposalFinish(@ApiParam("主键")
                                  @NotNull(message = "主键不能为空")
                                  @PathVariable("id") String id) {

        return iTaskService.disposalFinish(id) ? R.ok("更新成功") : R.fail("更新失败");
    }


    @ApiOperation("查询处置暂存列表")
    @SaCheckPermission("oms:disposal:tempStorageList")
    @GetMapping("/getTempStorageList")
    public TableDataInfo<DisposalTempStorageBo> getTempStorageList(@Validated(QueryGroup.class) DisposalTempStorageBo bo, PageQuery pageQuery) {

        return TableDataInfo.build(disposalTaskService.getTempStorageList(pageQuery, bo));
    }

    @ApiOperation("导出处置暂存报表")
    @SaCheckPermission("wms:deal:export")
    @PostMapping("/exportTempStorageList")
    public void export(@Validated DisposalTempStorageBo bo, HttpServletResponse response) {

        ExcelUtil.exportExcel(disposalTaskService.getTempStorageListExport(bo), "处置暂存报表",
                DisposalTempStorageBo.class, response);
    }


    @ApiOperation("处置暂存")
    @SaCheckPermission("oms:disposal:tempStorage")
    @PostMapping("/disposalTempStorage")
    @Validated
    @RepeatSubmit()
    @Transactional(rollbackFor = Exception.class)
    public R<Void> disposalTempStorage(@NotEmpty(message = "财物不能为空") @RequestBody List<String> ids) {

        // 修改库存状态
        if (!iInventoryService.tempStorage(ids)) {
            throw new ServiceException("暂存异常");
        }

        String logContent = "财物暂存";

        ids.forEach(item -> {

            InventoryVo inventoryVo = iInventoryService.queryById(item);

            commonService.savePropertyLog(inventoryVo.getPno(), item, inventoryVo.getName(), "0", logContent,
                    inventoryVo.getDeptId(),
                    item, inventoryVo.getStoreId(), inventoryVo.getNums(), null);
        });

        return R.ok();

    }

    @ApiOperation("取消处置暂存")
    @SaCheckPermission("oms:disposal:cancelTempStorage")
    @PostMapping("/cancelDisposalTempStorage")
    @Validated
    @RepeatSubmit()
    @Transactional(rollbackFor = Exception.class)
    public R<Void> cancelDisposalTempStorage(@NotEmpty(message = "财物不能为空") @RequestBody List<String> ids) {

        // 修改库存状态
        if (!iInventoryService.cancelTempStorage(ids)) {
            throw new ServiceException("取消暂存异常");
        }

        String logContent = "财物取消暂存";

        ids.forEach(item -> {

            InventoryVo inventoryVo = iInventoryService.queryById(item);

            commonService.savePropertyLog(inventoryVo.getPno(), item, inventoryVo.getName(), "0", logContent,
                    inventoryVo.getDeptId(),
                    item, inventoryVo.getStoreId(), inventoryVo.getNums(), null);
        });

        return R.ok();

    }

}
